﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;
using System.Text;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;

namespace blackhouse.Web {
	public static class WebUtils {

		public delegate T CacheCallback<T>(string exData);

		public static T GetFromPageCache<T>(string name, CacheCallback<T> callback)
			where T : class {
			Page crnPage = getPage();
			T obj = null;
			if (crnPage != null && crnPage.Items.Contains(name))
				obj = crnPage.Items[name] as T;
			if (obj == null) {
				obj = callback("");
				SetInPageCache(name, obj);
			}
			return obj;
		}

		public static string GetNewAddress(string basedAddress, IDictionary<string, string> newParameters, List<string> removeParameters) {
			Uri url = new Uri(basedAddress);
			return GetNewAddress(url, newParameters, removeParameters);
		}

		public static string GetNewAddress(HttpRequest request, IDictionary<string, string> newParameters, List<string> removeParameters) {
			return GetNewAddress(request.Url, newParameters, removeParameters);
		}

		public static string GetNewAddress(Uri basedUrl, IDictionary<string, string> newParameters, List<string> removeParameters) {
			NameValueCollection parameters = new NameValueCollection();
			string[] aQuery = basedUrl.Query.ReplaceEx("?", "").Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
			for (int xq = 0; xq < aQuery.Length; xq++) {
				string[] aQueryPart = aQuery[xq].Split('=');
				parameters.Add(aQueryPart[0], aQueryPart[1]);
			}
			IDictionary<string, string> newQParameters = GetNewQueryParameters(parameters, newParameters, removeParameters);
			StringBuilder newUrl = new StringBuilder(basedUrl.GetLeftPart(UriPartial.Authority) + basedUrl.AbsolutePath);
			foreach (KeyValuePair<string, string> newValues in newQParameters) {
				newUrl.AppendFormat("&{0}={1}", newValues.Key, newValues.Value);
			}
			string sNewUrl = newUrl.ToString();
			int rpIdx = sNewUrl.IndexOf('&');
			sNewUrl = sNewUrl.Substring(0, rpIdx) + "?" + sNewUrl.Substring(rpIdx + 1);
			return sNewUrl;
		}

		public static IDictionary<string, string> GetNewQueryParameters(NameValueCollection queryParameters, IDictionary<string, string> newParameters, List<string> removeParameters) {
			Dictionary<string, string> returnNewParameters = new Dictionary<string, string>();
			foreach (string qpItem in queryParameters.AllKeys) {
				if (!removeParameters.Contains(qpItem)) {
					if (newParameters.ContainsKey(qpItem))
						returnNewParameters.Add(qpItem, newParameters[qpItem]);
					else
						returnNewParameters.Add(qpItem, queryParameters[qpItem]);
				}
			}

			foreach (KeyValuePair<string, string> newValues in newParameters) {
				if (!returnNewParameters.ContainsKey(newValues.Key))
					returnNewParameters.Add(newValues.Key, newValues.Value);
			}
			return returnNewParameters;
		}

		public static string GetTextFromHtml(string html) {
			Regex regsvr = new Regex("</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)/?>");
			return regsvr.Replace(html, "");
		}

		public static void SetInPageCache(string name, object obj) {
			Page crnPage = getPage();
			if (crnPage != null)
				crnPage.Items[name] = obj;
		}

		private static Page getPage() {
			return HttpContext.Current.Handler as Page;
		}

		public static IEnumerable<T> CutToPage<T>(IEnumerable<T> fullCollection, int page, int perPage) {
			int startFrom, endTo;
			return CutToPage<T>(fullCollection, page, perPage, out startFrom, out endTo);
		}

		public static IEnumerable<T> CutToPage<T>(IEnumerable<T> fullCollection, int page, int perPage, out int startFrom, out int endTo) {
			startFrom = perPage * (page - 1);
			endTo = startFrom + perPage;
			if (fullCollection.Count() < startFrom) {
				startFrom = -1;
				endTo = -1;
				return new List<T>();
			}
			IEnumerable<T> data = fullCollection.Skip(startFrom).Take(perPage);
			startFrom++;
			return data;
		}

		public static string[] ReadSelectedValues(this CheckBoxList checkbox) {
			IEnumerable<string> allKeys = HttpContext.Current.Request.Form.AllKeys.Where(s => s.StartsWith(checkbox.UniqueID));
			List<string> values = new List<string>(allKeys.Count());
			foreach (string key in allKeys) {
				int idx = Int32.Parse(key.ReplaceEx(checkbox.UniqueID, "").ReplaceEx("$", ""));
				values.Add(checkbox.Items[idx].Value);
			}
			return values.ToArray();
		}

		private const string MatchEmailPattern =
			@"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
	 + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
	 + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?
				[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
	 + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";

		public static bool IsValidEmail(this string email) {
			if (email != null) return Regex.IsMatch(email, MatchEmailPattern);
			else return false;
		}

	}
}